package com.mvp.networking;

import com.mvp.base.LoadMvpView;
import com.mvp.base.NetParams;

import io.reactivex.Observable;
import io.reactivex.ObservableSource;
import io.reactivex.ObservableTransformer;
import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.annotations.NonNull;
import io.reactivex.schedulers.Schedulers;

/**
 * ================================================
 * Created by ${chenyuexueer}
 * 说明：实现ObservableTransformer，完成线程切换，使用compose()操作符
 * <p>
 * 与 flatMap 有什么不一样么
 * <p>
 * flatMap：是把T转成Observable<R>
 * <p>
 * ObservableTransformer：是把Observable<T>转成Observable<R>
 * ================================================
 */

public class NetTransformer<T> implements ObservableTransformer<T, T> {
    private LoadMvpView loadMvpView;//弹出菊花窗口的对象
    private NetParams netParams;

    private NetTransformer() {
    }

    public NetTransformer(LoadMvpView loadMvpView) {
        this(loadMvpView, new NetParams());
    }

    public NetTransformer(LoadMvpView loadMvpView, NetParams netParams) {
        this.loadMvpView = loadMvpView;
        this.netParams = netParams;
    }

    @Override
    public ObservableSource<T> apply(@NonNull Observable<T> upstream) {
        return
                upstream
                        //io线程订阅
                        .subscribeOn(Schedulers.io())
                        //遇到错误时重试,参数为重试几次
//                        .retry(2)
                        //io线程解除订阅
                        .unsubscribeOn(Schedulers.io())
                        // 切换UI线程
                        .observeOn(AndroidSchedulers.mainThread())
                        //.compose(ErrorTransformer<T>getInstance());
                        .doOnSubscribe(disposable -> {
                            if (loadMvpView != null) {
                                loadMvpView.showLoadingBar(netParams.getShowTag());
                            }
                        })
                        /*
                        doFinally 除了拥有 doAfterTerminate 的特性之外，还会在下游(downstream)取消时被调用。这是 doFinally 和 doAfterTerminate 最大的区别。
                         */
                        .doAfterTerminate(() -> {
                            if (loadMvpView != null) {
                                loadMvpView.dismissLoadingBar(netParams.getDississTag());
                            }
                        });
    }
}
